1. Polling the File System
Services are great for acting as a polling
mechanism. In this example we will be monitoring for files that are
being added to a specified directory. Whether these files come from
another computer, a specific user, MSMQ, an SQL job, or an FTP site with
the appropriate privileges, we can monitor for files that arrive and
then perform some predefined task. In this first section we will monitor
a specific directory for new text files. We will log an event for each
new text file that we find.
2. Adding a Module File
The service is going to continue to grow, so to
help to keep things cleaner and more readable, let’s add a module file
to the project. In the Solution Explorer, click the Tutorials project
icon and select Add Module. Name the file modService.vb and click Add.
As shown in Listing 1,
cut and paste the THREAD_WAIT definition from the Tutorials.vb file
into the modService.vb and change the definition from Private to Public.
Listing 1. Move the THREAD_WAIT definition to the modService file.
Module modService
Public Const THREAD_WAIT As Integer = 5000
|
Adding Event Log InstanceIds
I want to define some custom InstanceIds
that we can use specifically when we log an event to the event log.
Currently we are just hard-coding them, but adding definitions for them
would be cleaner. So add the code shown in Listing 2 to your modService file.
Listing 2. New program constants.
Public Const ONSTART_ERROR As Integer = 1000
Public Const ONSTOP_ERROR As Integer = 1001
Public Const THREAD_ERROR As Integer = 1002
Public Const THREAD_ABORT_ERROR As Integer = 1003
Public Const ONSTART_INFO As Integer = 2000
Public Const ONSTOP_INFO As Integer = 2001
Public Const THREAD_INFO As Integer = 2002
Public Const ONPAUSE_INFO As Integer = 2003
Public Const ONCONTINUE_INFO As Integer = 2004
|
3. Adding New Polling Code
The next step is to create the code that will
look for these files and then add an event into the Application log. To
do this we must modify the current <ThreadFunc> method. Before we modify <ThreadFunc>, we need to add another import statement to the top of tutorials.vb that will
be used interact with the file system. Although the import is not
required, it makes it easier to create class instances of the IO
namespace without having to declare the entire namespace for each
variable declared.
Add the code shown in Listing 3 to the top of the Tutorials.vb file.
Listing 3. Add a new Imports statement.
We can now directly access the file system
classes used to check for any text files, without using the entire
namespace. We will also need a directory to monitor. You can create this
directory anywhere you want. I have created a directory called
“incoming” and placed it in my c:\temp directory.
Introduction to Instrumenting a Resource File
An important factor in programming is localization—displaying
information to a user based on the geographic locale or local language
used. You use a resource file and the .NET built-in localization
management methods to help make this happen.
We will implement a resource file to keep track
of any strings or text that we have previously coded into the service as
well as any new resource strings that we will add later on as we build
on the service.
Creating the Resource File
In addition to allowing us to handle
localization issues better, a resource file gives us the ability to
avoid issues such as passing literal strings to method calls, which
Microsoft discourages. To create the resource file, select the Tutorials
project name, right-click, and select Properties. Click the Resources
tab. If a resource file is not available, you will be prompted to create
one. After you have created the resource file you will see a grid
structure where you can enter string literals, names, and descriptions.
Not only will we add new strings, but also
previously coded literals. Then I will demonstrate how to access these
resources in your application.
First let’s add a string called IncomingPath and give it a value of c:\temp\incoming, or wherever you created your incoming folder. Leave the value for Description empty.
Adding Previous Literals to the Resource File
I have added the string literals shown in Table 1; we will use them to replace the currently hard-coded values in the service.
Table 1. List of Resources Created for This Service
Name | Value YYY |
---|
IncomingPath | c:\temp\incoming |
Source | Tutorials |
ServiceStarting | Tutorials Starting |
ServicePausing | Tutorials Pausing |
ServiceStopping | Tutorials Stopping |
ServiceContinuing | Tutorials Continuing |
ThreadMessage | Thread Function Information |
ThreadAbortMessage | Thread Function Abort Error |
ThreadErrorMessage | Thread Function Error |
ThreadName | Tutorials Worker Thread |
ThreadIOError | Thread Function IO Error - |
OutgoingPath | c:\temp\outgoing |
Microsoft Visual Basic makes it very easy to access resources through the Visual Basic My Object.
Using the My Object, you can access a resource by typing My.Resources.ResourceName. For instance, using the resource file you just created, My.Resources.IncomingPath returns the string c:\temp\incoming.